#include "maindialog.h"
#include "ui_maindialog.h"

#include <QMenu>
#include <QProcess>
#include <QMessageBox>
#include <KWindowSystem>
#include <KWindowEffects>
#include <unistd.h>
#include "xatom-helper.h"
#include "../common/mydefine.h"
#include "module/systembackup.h"
#include "module/systemrestore.h"
#include "module/databackup.h"
#include "module/datarestore.h"
#include "module/operationlog.h"
#include "module/ghostimage.h"
#include "backup_manager_interface.h"
#include "globalbackupinfo.h"
#include "messageboxutils.h"
#include "aboutdialog.h"
#include "gsettingswrapper.h"
#include "component/mywidget.h"
#include <ukuistylehelper/ukuistylehelper.h>
#include <windowmanager/windowmanager.h>

MainDialog::MainDialog(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainDialog)
{
    ui->setupUi(this);
    // 主窗口
    this->setWindowTitle(tr("Backup & Restore"));
    // 窗口背景透明化；setWindowOpacity可使得窗口及其上控件都透明或半透明-w.setWindowOpacity(0.7);
    this->setAttribute(Qt::WA_TranslucentBackground);
    // 使得窗口无边框
    // w.setWindowFlag(Qt::FramelessWindowHint);
    // 指示窗口管理器模糊给定窗口后面指定区域的背景(毛玻璃化背景)
    // KWindowEffects::enableBlurBehind(this->winId(), true);
    // 或使用设置毛玻璃属性的方式实现毛玻璃背景（两者都行，可使用其一）
    this->setProperty("useSystemStyleBlur", true);
    this->setAutoFillBackground(true);

    // 添加窗管协议
    if (GlobelBackupInfo::inst().isWayland()){
        // 去除窗管标题栏，传入参数为QWidget *
        kdk::UkuiStyleHelper::self()->removeHeader(this);
    } else {
        MotifWmHints hints;
        hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
        hints.functions = MWM_FUNC_ALL;
        hints.decorations = MWM_DECOR_BORDER;
        XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints);
    }

    GlobelBackupInfo::inst().setMainWidget(this);

    // 注册BackupWrapper类型，之后qdbus接口才能使用
    BackupWrapper::registerMetaType();
    mountBackupPartition();

    initUI();
    initConnect();
}

MainDialog::~MainDialog()
{
    delete ui;
}

void MainDialog::initUI()
{
    // 总体布局为横向布局，分为左侧和右侧
    m_totalHLayout = new QHBoxLayout;
    m_totalHLayout->setSpacing(0);
    m_totalHLayout->setObjectName(QString::fromUtf8("m_totalHLayout"));
    m_totalHLayout->setContentsMargins(0, 0, 0, 0);
    m_totalHLayout->setSpacing(0);
    ui->centralwidget->setLayout(m_totalHLayout);

    // 左栏窗口
    if (GlobelBackupInfo::inst().isManager())
        m_leftSiderBarWidget = new LeftsiderbarWidget(ui->centralwidget);
    else
        m_leftSiderBarWidget = new LeftsiderbarWidget(ui->centralwidget, LeftsiderbarWidget::StartMode::std_user);
    m_leftSiderBarWidget->setObjectName(QString::fromUtf8("m_leftSiderBarWidget"));
    m_leftSiderBarWidget->setFixedWidth(200);
    //m_leftSiderBarWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
    m_leftSiderBarWidget->initUi();

    m_totalHLayout->addWidget(m_leftSiderBarWidget);

    // 右侧窗口
    m_rightWidget = new MyWidget;
    //m_rightWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    m_rightVLayout = new QVBoxLayout;
    m_rightVLayout->setObjectName(QString::fromUtf8("m_rightVLayout"));
    m_rightVLayout->setContentsMargins(0, 0, 0, 0);
    m_rightVLayout->setSpacing(0);

    // 右侧窗口：标题栏
    m_titleWidget = new QWidget;
    m_titleWidget->setObjectName(QString::fromUtf8("m_titleWidget"));
    m_titleWidget->setFixedHeight(40);
    m_rightVLayout->addWidget(m_titleWidget);

    // 右侧窗口：工作区
    if (GlobelBackupInfo::inst().isManager() && GlobelBackupInfo::inst().hasArgRestore())
        selected(FuncTypeConverter::FunType::RESTORE_SYSTEM);
    else if (!GlobelBackupInfo::inst().isManager()  && GlobelBackupInfo::inst().hasArgRestore())
        selected(FuncTypeConverter::FunType::RESTORE_DATA);
    else if (!GlobelBackupInfo::inst().isManager())
        selected(FuncTypeConverter::FunType::BACKUP_DATA);
    else
        selected(FuncTypeConverter::FunType::BACKUP_SYSTEM);

    m_rightWidget->setLayout(m_rightVLayout);
    m_totalHLayout->addWidget(m_rightWidget);

    initTileBar();
}

#define PC_TITLE_BAR_SIZE 30
#define TABLET_TITLE_BAR_SIZE 48
void MainDialog::initTileBar()
{
    m_titleLayout = new QHBoxLayout;
    m_titleLayout->setContentsMargins(8, 4, 4, 0);
    m_titleLayout->setSpacing(4);

    m_menuOptionBtn  = new QToolButton;
    m_minBtn      = new QPushButton;
    m_maxBtn      = new QPushButton;
    m_closeBtn    = new QPushButton;

    m_menuOptionBtn->setToolTip(tr("Main menu"));
    m_minBtn->setToolTip(tr("Minimize"));
    m_maxBtn->setToolTip(tr("Maximize"));
    m_closeBtn->setToolTip(tr("Close"));

    m_menuOptionBtn->setProperty("isWindowButton", 0x1);
    m_menuOptionBtn->setProperty("useIconHighlightEffect", 0x2);
    m_menuOptionBtn->setIcon(QIcon::fromTheme("open-menu-symbolic"));
    m_menuOptionBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
    m_menuOptionBtn->setAutoRaise(true);
    m_menuOptionBtn->setPopupMode(QToolButton::InstantPopup);

    m_minBtn->setProperty("isWindowButton", 0x1);
    m_minBtn->setProperty("useIconHighlightEffect", 0x2);
    m_minBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
    m_minBtn->setFlat(true);
    m_minBtn->setIcon(QIcon::fromTheme("window-minimize-symbolic"));

    m_maxBtn->setProperty("isWindowButton", 0x1);
    m_maxBtn->setProperty("useIconHighlightEffect", 0x2);
    m_maxBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
    m_maxBtn->setFlat(true);
    m_maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic"));

    m_closeBtn->setProperty("isWindowButton", 0x2);
    m_closeBtn->setProperty("useIconHighlightEffect", 0x8);
    m_closeBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
    m_closeBtn->setFlat(true);
    m_closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));

    QMenu* backupMain = new QMenu(m_titleWidget);
    backupMain->setObjectName("mainMenu");
    m_menuOptionBtn->setMenu(backupMain);

    // 暂时只需跟随主题，浅色主题和深色主题后续可能会独立出来
//    QAction* backupTheme = new QAction(tr("Theme"), m_titleWidget);
//    backupMain->addAction(backupTheme);
//    QMenu* selectTheme = new QMenu( m_titleWidget);
//    selectTheme->setObjectName("selectTheme");
//    backupTheme->setMenu(selectTheme);
//    QAction* defaultTheme = new QAction(tr("Auto"), m_titleWidget);
//    selectTheme->addAction(defaultTheme);
//    QAction* lightTheme = new QAction(tr("Light"), m_titleWidget);
//    selectTheme->addAction(lightTheme);
//    QAction* darkTheme = new QAction(tr("Dark"), m_titleWidget);
//    selectTheme->addAction(darkTheme);

    m_backupHelp = new QAction(tr("Help"), m_titleWidget);
    m_backupHelp->setShortcut(QKeySequence::HelpContents);
    backupMain->addAction(m_backupHelp);
    m_backupAbout = new QAction(tr("About"), m_titleWidget);
    backupMain->addAction(m_backupAbout);
    m_backupExit = new QAction(tr("Exit"), m_titleWidget);
    backupMain->addAction(m_backupExit);

    m_titleLayout->addStretch();
    m_titleLayout->addWidget(m_menuOptionBtn);
    m_titleLayout->addWidget(m_minBtn);
    m_titleLayout->addWidget(m_maxBtn);
    m_titleLayout->addWidget(m_closeBtn);
    m_titleWidget->setLayout(m_titleLayout);
}

void MainDialog::initConnect()
{
    // 左侧功能选择栏
    connect(m_leftSiderBarWidget, &LeftsiderbarWidget::selected, this, &MainDialog::selected);

    // 标题栏右侧按钮区域
    // 退出
    connect(m_backupExit, &QAction::triggered, this, &MainDialog::closeBtn);

    // 关于
    connect(m_backupAbout, &QAction::triggered, this, [=] {
        AboutDialog *about = new AboutDialog(this);
        about->exec();
        about->deleteLater();
    });

    connect(m_backupHelp, &QAction::triggered, this, [=] {
        QProcess process(this);
        process.startDetached("kylin-user-guide -A kybackup");
    });

    //最小化按钮
    connect(m_minBtn, &QPushButton::clicked, this, &MainDialog::showMinimized);

    //最大化按钮
    connect(m_maxBtn, &QPushButton::clicked, this, [=] {
        if (isMaximized()) {
            showNormal();
        } else {
            showMaximized();
        }
    });

    //关闭按钮
    connect(m_closeBtn, &QPushButton::clicked, this, &MainDialog::closeBtn);

    //监听平板模式切换
    m_statusSessionDbus = new QDBusInterface("com.kylin.statusmanager.interface",
                                             "/",
                                             "com.kylin.statusmanager.interface",
                                             QDBusConnection::sessionBus(),
                                             this);
    if (m_statusSessionDbus->isValid()) {
        QDBusReply<bool> is_tabletmode = m_statusSessionDbus->call("get_current_tabletmode");
        GlobelBackupInfo::inst().setIsTabletMode(is_tabletmode);
        tabletModeChange(is_tabletmode);
        connect(m_statusSessionDbus, SIGNAL(mode_change_signal(bool)), this, SLOT(tabletModeChange(bool)));
    } else {
        GlobelBackupInfo::inst().setIsTabletMode(false);
        m_maxBtn->setVisible(true);
    }
}

/**
 * @brief 平板模式切换
 * @param isTabletMode  true-平板模式；false-PC模式
 */
void MainDialog::tabletModeChange(bool isTabletMode)
{
    GlobelBackupInfo::inst().setIsTabletMode(isTabletMode);
    if(isTabletMode){
        m_menuOptionBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
        m_minBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
        m_maxBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
        m_closeBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
        m_titleWidget->setFixedHeight(56);
        m_maxBtn->setVisible(false);
    } else {
        m_menuOptionBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
        m_minBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
        m_maxBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
        m_closeBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
        m_titleWidget->setFixedHeight(40);
        m_maxBtn->setVisible(true);
    }
}

void MainDialog::changeEvent(QEvent *event)
{
    if (QEvent::WindowStateChange == event->type()) {
        Qt::WindowStates state = this->windowState();
        switch (state) {
        case Qt::WindowMaximized:
        case Qt::WindowFullScreen:
            m_maxBtn->setIcon(QIcon::fromTheme("window-restore-symbolic"));
            m_maxBtn->setToolTip(tr("Normal"));

            break;
        case Qt::WindowNoState:
            m_maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic"));
            m_maxBtn->setToolTip(tr("Maximize"));

            break;
        default:
            break;
        }
    }

    QMainWindow::changeEvent(event);
}

/**
 * @brief 左侧功能选择栏响应槽
 * @param func_type，功能类型
 */
void MainDialog::selected(int func_type)
{
    if (GlobelBackupInfo::inst().getFuncType() == func_type)
        return ;

    if (m_stackedWidget) {
        m_rightVLayout->removeWidget(m_stackedWidget);
        delete m_stackedWidget;
    }

    switch (func_type) {
    case FuncTypeConverter::FunType::BACKUP_SYSTEM:
        m_stackedWidget = new SystemBackup(m_rightWidget);
        GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM);
        break;
    case FuncTypeConverter::FunType::RESTORE_SYSTEM:
        m_stackedWidget = new SystemRestore(m_rightWidget);
        GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::RESTORE_SYSTEM);
        break;
    case FuncTypeConverter::FunType::BACKUP_DATA:
        m_stackedWidget = new DataBackup(m_rightWidget);
        GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_DATA);
        break;
    case FuncTypeConverter::FunType::RESTORE_DATA:
        m_stackedWidget = new DataRestore(m_rightWidget);
        GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::RESTORE_DATA);
        break;
    case FuncTypeConverter::FunType::OPERATION_LOG:
        m_stackedWidget = new OperationLog(m_rightWidget);
        GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::OPERATION_LOG);
        break;
    case FuncTypeConverter::FunType::GHOST_IMAGE:
        m_stackedWidget = new GhostImage(m_rightWidget);
        GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::GHOST_IMAGE);
        break;
    default:
        m_stackedWidget = new SystemBackup(m_rightWidget);
        GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM);
        break;
    }

    m_stackedWidget->setObjectName(QString::fromUtf8("m_stackedWidget"));
    // m_stackedWidget->setMinimumSize(760, 600);
    m_rightVLayout->addWidget(m_stackedWidget);

    m_leftSiderBarWidget->setCheckedFunc(func_type);
}

/**
 * @brief 多例启动信息槽
 * @param msg 信息，里面存放新启动实例的账户id
 */
void MainDialog::sltMessageReceived(const QString &msg)
{
    QString user = QString::number(getuid());
    if (msg == user) {
//        this->setWindowFlag(Qt::WindowStaysOnTopHint,true);
//        this->setWindowFlag(Qt::WindowStaysOnTopHint,false);
        KWindowSystem::forceActiveWindow(this->winId());
        this->show();
    }
}

void MainDialog::mountBackupPartition()
{
    // 挂载/backup分区
    ComKylinBackupManagerInterface intf("com.kylin.backup", "/", QDBusConnection::systemBus());
    QDBusPendingReply<int> reply = intf.Mount_backup_partition();
    reply.waitForFinished();
    if (reply.isError()) {
        // 挂载分区时出现异常
        MessageBoxUtils::QMESSAGE_BOX_CRITICAL(this, QObject::tr("Warning"),
                                              QObject::tr("An exception occurred when mounting backup partition."),
                                              QObject::tr("Ok"));

        // 此时还未进入应用的事件循环中，故不能使用qApp->quit();
        exit(1);
    } else if (int(MountResult::CANNOT_GET_BACKUPUUID) == reply.value()) {
        // 没有找到备份分区，只能备份到移动设备中
//        MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Information"),
//                                              QObject::tr("Please check if the backup partition exists which can be created when you install the Operating System."),
//                                              QObject::tr("Ok"));
//        // 此时还未进入应用的事件循环中，故不能使用qApp->quit();
//        exit(1);
        GlobelBackupInfo::inst().setHasBackupPartition(false);
    } else if (int(MountResult::MOUNTED) != reply.value()) {
        // 挂载备份分区失败
        MessageBoxUtils::QMESSAGE_BOX_CRITICAL(this, QObject::tr("Warning"),
                                              QObject::tr("Failed to mount backup partition."),
                                              QObject::tr("Ok"));

        // 此时还未进入应用的事件循环中，故不能使用qApp->quit();
        exit(1);
    }
}

void MainDialog::umountBackupPartition()
{
    // 卸载/backup分区
    ComKylinBackupManagerInterface intf("com.kylin.backup", "/", QDBusConnection::systemBus());
    intf.umountBackupPartition();
}

void MainDialog::closeEvent(QCloseEvent *e)
{
    if (GlobelBackupInfo::inst().isBusy()) {
        // 系统正忙，请稍等
        MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
                                              QObject::tr("It's busy, please wait"),
                                              QObject::tr("Ok"));

        e->ignore();
        return;
    }

    if (GlobelBackupInfo::inst().hasBackupPartition())
        umountBackupPartition();

    e->accept();
}

void MainDialog::resizeEvent(QResizeEvent *event) {
    emit GlobelBackupInfo::inst().getGlobalSignals()->widthChanged();
    QMainWindow::resizeEvent(event);
}

void MainDialog::closeBtn()
{
    if (this->close()) {
        qApp->quit();
    }
}

